package com.zbkj.admin.controller.platform.assistant.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.admin.controller.platform.assistant.service.AssistantConversationService;
import com.zbkj.admin.controller.platform.assistant.service.AssistantMessageService;
import com.zbkj.common.constants.AssistantConstants;
import com.zbkj.common.constants.Constants;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.assistant.AssistantConversation;
import com.zbkj.common.model.assistant.AssistantMessage;
import com.zbkj.common.model.assistant.AssistantSetting;
import com.zbkj.common.netty.AcceptDataContent;
import com.zbkj.common.netty.AcceptMessage;
import com.zbkj.common.netty.CustomerServiceInfo;
import com.zbkj.common.netty.UserInfo;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.result.AssistantResultCode;
import com.zbkj.service.assistant.model.request.AssistantMessageAdminSearchRequest;
import com.zbkj.service.assistant.model.request.AssistantMessageAdminSendRequest;
import com.zbkj.service.assistant.model.vo.AssistantMessageVO;
import com.zbkj.service.assistant.service.AssistantMessageBaseServiceImpl;
import com.zbkj.service.service.SendMessageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author keNan
* @description AssistantMessageServiceImpl 接口实现
* @date 2025-06-11
*/
@Slf4j
@Primary
@Service
@RequiredArgsConstructor
public class AssistantMessageServiceImpl extends AssistantMessageBaseServiceImpl implements AssistantMessageService {
    private final AssistantConversationService assistantConversationService;

    private final SendMessageService sendMessageService;

    @Override
    public List<AssistantMessageVO> findByConversationId(Integer conversationId) {
        List<AssistantMessage> list = super.lambdaQuery()
            .eq(AssistantMessage::getConversationId, conversationId)
            .list();
        return list.stream().map(x -> {
            AssistantMessageVO vo = new AssistantMessageVO();
            BeanUtils.copyProperties(x, vo);
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public AssistantMessageVO getLastMessage(Integer conversationId) {
        AssistantMessage lastMessage = super.lambdaQuery()
            .eq(AssistantMessage::getConversationId, conversationId)
            .ne(AssistantMessage::getSenderType, 0)
            .orderByDesc(AssistantMessage::getId)
            .last("limit 1")
            .one();
        AssistantMessageVO vo = new AssistantMessageVO();
        BeanUtil.copyProperties(lastMessage, vo);
        return vo;
    }

    @Override
    public Integer getUnreadCount(Integer userId) {
        return super.lambdaQuery()
            .eq(AssistantMessage::getSenderType, 1)
            .eq(AssistantMessage::getUserId, userId)
            .eq(AssistantMessage::getIsAdminRead, false)
            .count();
    }

    @Override
    @Transactional
    public AssistantMessageVO sendByAdmin(AssistantMessageAdminSendRequest request, Integer adminId) {
        AssistantConversation conversation = assistantConversationService.getById(request.getConversationId());
        if (ObjUtil.isEmpty(conversation)) {
            throw new CrmebException(AssistantResultCode.ASSISTANT_CONVERSATION_NOT_EXIST);
        }
        if (!AssistantConstants.Conversation.STATUS_SERVICE.equals(conversation.getStatus())) {
            throw new CrmebException(AssistantResultCode.CONVERSATION_NOT_SERVICE);
        }
        if (!adminId.equals(conversation.getServiceAccountId())) {
            throw new CrmebException(AssistantResultCode.CONVERSATION_NOT_YOURS);
        }
        AssistantMessage param = new AssistantMessage()
            .setConversationId(request.getConversationId())
            .setSenderType(2)
            .setUserId(conversation.getUserId())
            .setSenderId(adminId)
            .setContentType(request.getContentType())
            .setContent(request.getContent())
            .setServiceAvatar(conversation.getServiceAvatar())
            .setServiceName(conversation.getServiceName())
            .setUserAvatar(conversation.getUserAvatar())
            .setUserName(conversation.getUserName());
        super.checkMessageContent(param);
        super.save(param);
        assistantConversationService.updateAddMsgCount(request.getConversationId(), 0, 1);

        AssistantMessage dbMessage = super.getById(param.getId());
        try {
            AcceptMessage acceptMessage = new AcceptMessage().setMessageContent(request.getContent()).setAssistantMessage(dbMessage);
            UserInfo userInfo = new UserInfo().setType(1).setUserId(conversation.getUserId());
            CustomerServiceInfo customerServiceInfo = new CustomerServiceInfo().setType(11).setUserId(adminId);
            AcceptDataContent acceptDataContent = new AcceptDataContent()
                .setUserInfo(userInfo)
                .setCustomerServiceInfo(customerServiceInfo)
                .setAcceptMessage(acceptMessage)
                .setMessageType(request.getContentType())
                .setUserType(2)
                .setToUserType(1)
                .setSecret(Constants.CHANNEL_SECRET_SEND_MESSAGE);
            sendMessageService.sendMessage(acceptDataContent);
        } catch (Exception e) {
            log.error("发送消息失败", e);
        }
        AssistantMessageVO vo = new AssistantMessageVO();
        BeanUtil.copyProperties(dbMessage, vo);
        return vo;
    }

    @Override
    public PageInfo<AssistantMessageVO> getAdminMessageList(AssistantMessageAdminSearchRequest request, PageParamRequest pageParamRequest) {
        Integer userId = request.getUserId();
        if (ObjUtil.isNull(userId) && ObjUtil.isNotEmpty(request.getConversationId())){
            AssistantConversation conversation = assistantConversationService.getById(request.getConversationId());
            if (ObjUtil.isNotEmpty(conversation))
                userId = conversation.getUserId();
        }
        Page<AssistantMessage> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<AssistantMessage> list = super.lambdaQuery()
            .eq(ObjUtil.isNotEmpty(userId), AssistantMessage::getUserId, userId)
            .orderByDesc(AssistantMessage::getCreateTime, AssistantMessage::getId)
            .list();

        List<AssistantMessageVO> vos = list.stream().map(x -> {
            this.checkReadMessage(x);

            AssistantMessageVO vo = new AssistantMessageVO();
            BeanUtils.copyProperties(x, vo);
            return vo;
        }).collect(Collectors.toList());
        return CommonPage.copyPageInfo(page, vos);
    }

    @Override
    public Boolean checkIsTimeout(AssistantSetting setting, AssistantConversation conversation) {
        AssistantMessageVO lastMessage = this.getLastMessage(conversation.getId());
        if (ObjUtil.isEmpty(lastMessage)) {
            return false;
        }

        if (AssistantConstants.Message.SENDER_TYPE_USER.equals(lastMessage.getSenderType())) {
            return false;
        }

        if (lastMessage.getCreateTime().getTime() + setting.getConversationTimeout() * 60 * 1000 > System.currentTimeMillis()) {
            return false;
        }

        return true;
    }

    @Override
    public void read(Integer messageId) {
        AssistantMessage message = super.getById(messageId);
        if (ObjUtil.isNull(message))
            return;
        this.checkReadMessage(message);
    }

    private void checkReadMessage(AssistantMessage message) {
        if (!message.getIsAdminRead()) {
            super.lambdaUpdate()
                .eq(AssistantMessage::getId, message.getId())
                .set(AssistantMessage::getIsAdminRead, true)
                .set(AssistantMessage::getAdminReadTime, new Date())
                .update();
        }
    }

}

